package net.bingosoft.common;

import java.util.Locale;

import net.bingosoft.common.config.Config;
import net.bingosoft.common.data.BaseDao;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.access.BeanFactoryLocator;
import org.springframework.beans.factory.access.BeanFactoryReference;
import org.springframework.context.ApplicationContext;
import org.springframework.context.access.ContextSingletonBeanFactoryLocator;
/**
 * 2007-10-10 下午01:38:01
 * Author:yangdongyu(yangdy@bingosoft.net)
 * ReadMe:对象注册表,用户获取beanRefContext.xml中指定的bean或消息
 * ChangeLog:
 */
public class ObjectRegistry {
	private static final Log log = LogFactory.getLog(ObjectRegistry.class);
	private static ApplicationContext context;
	private static ApplicationContext overrideApplicationContext ;
	private static final Object lock = new Object();
	private static String baseDaoId = Config.getString("BASEDAO_BEANID", "baseDao");
	/**
	 * 设置Override的beanfacotry,如果用户设置了overrideFactory,则在获取bean的时候,优先查询overrideFactory
	 * @param overrideFactory
	 */
	public static void setOverrideFactory(ApplicationContext overrideFactory) {
		ObjectRegistry.overrideApplicationContext = overrideFactory;
	}
	/**
	 * 初始化ApplicationContext
	 * @return
	 */
	private static ApplicationContext initApplicationContext(){
		log.debug("开始初始化BeanFactory");
		ApplicationContext context;
		long start = System.currentTimeMillis();
		if(ObjectRegistry.overrideApplicationContext != null){
			log.debug("init ApplicationContext by ObjectRegistry.overrideApplicationContext ...");
			context = ObjectRegistry.overrideApplicationContext ;
		}else{
			log.debug("init ApplicationContext by beanRefContext.xml ...");
			BeanFactoryLocator bfl = ContextSingletonBeanFactoryLocator.getInstance() ;
			BeanFactoryReference bf = bfl.useBeanFactory( "OBJ_REGISTRY" );
			context = (ApplicationContext)bf.getFactory();
		}
		long end = System.currentTimeMillis();
		log.debug("BeanFactory初始化完毕,耗时" + (end - start) + "ms");
		return context;

	}
	/**
	 * 获取beanRefContext.xml 定义的bean
	 * @param beanId bean id
	 * @return
	 */
	public static Object getBean( final String beanId ){		
		return getApplicationContext().getBean( beanId )  ;
	}
	/**
	 * 获取beanRefContext.xml 定义的bean
	 * @param <T> 泛型参数
	 * @param beanId bean id
	 * @param returnType 返回bean类型
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static <T> T getBean( final String beanId ,final Class <T> returnType){		
		return (T)getApplicationContext().getBean( beanId ,returnType)  ;
	}
	/**
	 * 获取Spring的消息
	 * @param key 消息在spring指定的messageSource 资源文件中对应的键值
	 * @param defaultMessage 找不到指定消息时返回的默认消息
	 * @param args 消息对应的填充参数
	 * @return
	 */
	public static String getMessage( final String key, final String defaultMessage, final Object... args){
		return context.getMessage(key, args, defaultMessage, Locale.getDefault());
	}
	/**
	 * 获取本地化的消息
	 * @param key 消息在spring指定的messageSource 资源文件中对应的键值
	 * @param defaultMessage 找不到指定消息时返回的默认消息
	 * @param args 消息对应的填充参数
	 * @return
	 */
	public static String getLocaleMessage(Locale locale,String key,String... args){
		return context.getMessage(key, args, key, locale);
	}
	public static ApplicationContext getApplicationContext(){
		synchronized (lock) {
			if(context == null){
				context = initApplicationContext();
			}
		}
		return context;
	}
	/**
	 * 获取baseDao的实现
	 * @return
	 */
	public static BaseDao getBaseDao(){
		return getBean(baseDaoId, BaseDao.class);
	}
	/**
	 * 获取针对特定数据源的dao
	 * @param datasourceKey
	 * @return
	 */
	public static BaseDao getBaseDao(String datasourceKey){
		return getBaseDao().getBaseDao(datasourceKey);
	}
	/**
	 * 检查该beanfactory是否包含指定的bean
	 * @param beanId
	 * @return
	 */
	public static boolean containsBean(String beanId){
		return getApplicationContext().containsBean(beanId);
	}


}